package com.regent.central.bill.service;

import com.regent.central.bill.common.SaleOrderType;
import com.regent.central.bill.core.SaleOrder;
import com.regent.central.bill.dto.delivery.DeliverySaleOrderDTO;
import com.regent.central.bill.dto.sale_order.*;
import com.regent.central.infrastructure.service.DomainService;

import java.math.BigDecimal;
import java.util.List;

public interface SaleOrderService extends DomainService<SaleOrder> {

    Integer getMaxOrderNoOfUnitIdAndOrderDay(String unitID, String orderDay);

    void setMerchandiser(String orderId, String merchandiserId);

    void setAddress(String orderId, String addressId);

    BigDecimal getLastPrice(String unitId, String goodsId, String customerId);

    List<SaleOrderListDTO> getHistoryOrderList(String unitId, String customerId, String startSearchTime, int pageNo, int pageSize);

    List<SaleOrderListDTO> getHistoryStyleOrderList(String unitId, String customerId, String startSearchTime, String styleId, int pageNo, int pageSize);

    List<DeliverySaleOrderDTO> getOwedSaleOrders(
            String unitId,
            String customerId,
            String startSearchTime,
            String startTime,
            String endTime,
            String sortBy,
            Integer sortAs,
            String keyword,
            int pageNo,
            int pageSize
    );

    /**
     * 更新本单应付 ∑（sku开单数×sku开单单价 ± sku改欠货数×sku开单单价 -sku 退货数×sku退货单价） - 抹零金额 + ∑核进金额 - ∑核出金额
     *
     * @param saleOrderId 销售单ID
     */
    void updateAmountExpected(String saleOrderId);

    /**
     * 更新总收/退款 ∑（所有收/退款记录金额）
     *
     * @param saleOrderId 销售单ID
     */
    void updateAmountArrived(String saleOrderId);

    /**
     * 更新总核进/核出金额 ∑（核进/出金额）
     *
     * @param saleOrderId 销售单ID
     */
    void updateAmountCleared(String saleOrderId);

    /**
     * 更新结欠金额 ∑（sku开单数×sku开单单价 ± sku改欠货数×sku开单单价 -sku 退货数×sku退货单价） - 抹零金额 + ∑核进金额 - ∑核出金额 - ∑收款账户收退款金额
     *
     * @param saleOrderId 销售单ID
     */
    void updateAmountRemain(String saleOrderId);

    /**
     * 更新销售总数 ∑（sku开单数） ± ∑（sku改欠货数）
     *
     * @param saleOrderId 销售单ID
     */
    void updateTotalSold(String saleOrderId);

    /**
     * 更新开单总数 ∑（sku开单数）
     *
     * @param saleOrderId 销售单ID
     */
    void updateTotalCreated(String saleOrderId);

    /**
     * 更新改他单总数 ∑（sku改欠货数）
     *
     * @param saleOrderId 销售单ID
     */
    void updateTotalModified(String saleOrderId);

    /**
     * 更新退货总数 ∑（sku退货数）
     *
     * @param saleOrderId 销售单ID
     */
    void updateTotalReturned(String saleOrderId);

    /**
     * 更新发货总数 ∑（发货sku）
     *
     * @param saleOrderId 销售单ID
     */
    void updateTotalDelivered(String saleOrderId);

    /**
     * 更新总欠货数 ∑（sku开单数） ± ∑（sku被改欠货数） - ∑（发货sku）
     *
     * @param saleOrderId 销售单ID
     */
    void updateTotalOwed(String saleOrderId);

    /**
     * 更新总开单金额 ∑(sku开单数×sku金额)
     *
     * @param saleOrderId 销售单ID
     */
    void updateAmountCreated(String saleOrderId);

    /**
     * 更新总改单金额 ∑(sku改欠货数×sku金额)
     *
     * @param saleOrderId 销售单ID
     */
    void updateAmountModified(String saleOrderId);

    /**
     * 更新总退货金额 ∑(sku退货数×sku金额)
     *
     * @param saleOrderId 销售单ID
     */
    void updateAmountReturned(String saleOrderId);

    /**
     * 查询销售单
     *
     * @param unitId          组织ID
     * @param startTime       开始时间
     * @param endTime         结束时间
     * @param userIds         用户ID
     * @param types           单据类型
     * @param saleOrderStatus 销售单状态
     * @param receiptStatus   收款单状态
     * @param startSearchTime 开始搜索时间
     * @param pageNo          页码
     * @param pageSize        每页最大数量
     * @return 销售单集合
     */
    List<SaleOrderQueryDTO> query(
            String unitId,
            String startTime,
            String endTime,
            List<String> userIds,
            List<SaleOrderType> types,
            List<SaleOrderQueryStatus> saleOrderStatus,
            List<ReceiptQueryStatus> receiptStatus,
            String startSearchTime,
            int pageNo,
            int pageSize
    );

    /**
     * 销售单详情
     *
     * @param saleOrderId 销售单ID
     * @return 销售单详情, 如果不存在则返回 {@code null}
     */
    SaleOrderDetailDTO detail(String saleOrderId);

    /**
     * 获取销售单抹零金额
     *
     * @param saleOrderId 销售单ID
     * @return 销售单抹零金额
     */
    BigDecimal getSaleOrderOddment(String saleOrderId);

    /**
     * 设置销售单的抹零金额
     *
     * @param saleOrderId 销售单ID
     * @param oddment     抹零金额
     */
    void setOddment(String saleOrderId, BigDecimal oddment);

    /**
     * 撤销销售单
     *
     * @param saleOrderId 销售单ID
     */
    void cancel(String saleOrderId);

    /**
     * 查询可核销的销售单列表
     *
     * @param unitId          组织ID
     * @param customerId      客户ID
     * @param startSearchTime 开始搜索时间
     * @param pageNo          页码
     * @param pageSize        每页最大条数
     * @return 可核销的销售单列表
     */
    List<SaleOrderQueryDTO> clearables(
            String unitId,
            String customerId,
            String startSearchTime,
            int pageNo,
            int pageSize
    );

}